package com.nowcoder.community.z_util;

import org.apache.commons.lang3.CharUtils;
import org.apache.commons.lang3.StringUtils;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;

import javax.annotation.PostConstruct;
import javax.sound.midi.Soundbank;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>——————————————————————————————————————————————-————
 * <p>   【名字】敏感词工具类【所属包】com.nowcoder.community.z_util
 * <p>
 * <p>   【谁调用我】讨论区发布的String内容
 * <p>
 * <p>   【调用我干什么】替换敏感词为*****
 * <p>——————————————————————————————————————————————-————
 */

@Component
public class MinGanF {



    //全局变量
    public TrieNode rot = new TrieNode();//根节点【背：前缀树必须这么】


    //准备
    public class TrieNode{
        //不用val?,因为：1 rot为“”空 + 2 map存所有儿子
        boolean curisEnd = false;//是否是一个敏感词结束

        Map<Character,TrieNode> nextM = new HashMap<>();
    }
    // 判断是否为符号
    public boolean isSymbol(Character c) {
        // 0x2E80~0x9FFF 是东亚文字范围
        return !CharUtils.isAsciiAlphanumeric(c) && (c < 0x2E80 || c > 0x9FFF);
    }

    @PostConstruct//必须spring注入才能用@
    //开始
    public void init(){
        insertW("猫坚强");
        insertW("小出纳");
        insertW("周老二");
    }
    //插入【1】个单词，for即可，不用递归
    public void insertW(String mgW){
        char[] cs = mgW.toCharArray();
        TrieNode t = rot;//防止改全局

        for(char c:cs){
            //先看看rot的map第一层是否有
            if(t.nextM.containsKey(c)){
                //x 进入下一层
                t=t.nextM.get(c);
            }
            else if(!t.nextM.containsKey(c)){
                //h 如果没找到，就要创啦
                TrieNode newN = new TrieNode();
                t.nextM.put(c,newN);
                //x
                t = newN;
            }
        }
        //结束设置当前这1个单词的end
        t.curisEnd=true;
    }



    //查找-双指针 滑窗2号easy
    public  String guolv(String text){
        StringBuilder s = new StringBuilder(text);

        char[] c = s.toString().toCharArray();
        int l=0;int r=0;
        TrieNode tr = rot;
        while(r<s.length()){
            r++;//r超1-滑窗2号也是
            if(r<s.length() && tr.nextM.containsKey(c[r-1])){
                l=r-1;
                tr = tr.nextM.get(c[r-1]);
                r++;
                while(r<s.length()) {
                    //先判符号
                    if(isSymbol(c[r-1])){
                        r++;
                        continue;//关键：终止本轮！
                    }
                    //后判敏感词map
                    else if(!(tr.nextM.containsKey(c[r-1])))break;//错3：卡一下
                    else if(tr.nextM.containsKey(c[r-1])){
                        r++;

                        if( tr.nextM.get(c[r-2]).curisEnd=true){
                            String th="";
                            for(int k=l;k<r;k++)th+='*';
                            s.replace(l,r+1,th);
                            break;
                        }
                        tr = tr.nextM.get(c[r-1]);//错1：没换下一个节点tr
                    }
                }
                tr = rot;//错4：没还原根
            }
        }

        return s.toString();
    }

    public static void main(String[] args) {
        MinGanF a = new MinGanF();
        String s = a.guolv("小出纳");
        System.out.println(s);
    }
    /*明白了 实际项目文件中不能加test*/

    //    @Test
    //    public void T(){
    //        //        StringBuilder a = new StringBuilder("nihao");
    //        //        a.replace(1,3,"*");
    //        insertW("猫坚强");
    //        insertW("小出纳");
    //        insertW("周老二");
    //        StringBuilder sb = new StringBuilder("我是，小，出纳，，猫-%%#￥@#坚-强爱-和，周老二吃零事");
    //        f(sb);
    //        System.out.println(sb);
    //    }
}
